#pragma once
#include "FoGGEDef.h"
#include "logger.h"

//note..
/*
the concept of GV is referenced from quake3 arena's CVER
*/


namespace _FOGGE_
{
	namespace _GDB_
	{

		class GeneralVariable;
		__interface iGeneralVariableManager
		{
			void ClearAllVariable();

			GeneralVariable* FindGeneralVariable(const char* name);
			bool RegisterGeneralVariable(GeneralVariable* gv);
		};



		class GeneralVariable
		{

			friend class GVMImplement;
		public:
			GeneralVariable(::_FO_GDB::GVContainer* ptrGVContainer, ::_FO_UTIL::Name name,::_FO_UTIL::Name type);

			~GeneralVariable(void);

			enum eGVFlag
			{
				eGVF_Archive=			1,	// set to cause it to be saved to vars.rc
											// used for system variables, not for player
											// specific configurations
				eGVF_UserInfo=			2,	// sent to server on connect or change
				eGVF_ServerInfo=		4,	// sent in response to front end requests
				eGVF_Systeminfo=		8,	// these cvars will be duplicated on all clients
				eGVF_Init=				16,	// don't allow change from console at all,
											// but can be set from the command line
				eGVF_Latch=				32,	// will only change when C code next does
											// a Cvar_Get(), so it can't be changed
											// without proper initialization.  modified
											// will be set, even though the value hasn't
											// changed yet
				eGVF_Rom=				64,	// display only, cannot be set by user at all
				eGVF_UserCreated=		128,	// created by a set command
				eGVF_Temp=				256,	// can be set even when cheats are disabled, but is not archived
				eGVF_Cheat=				512,	// can not be changed if cheats are disabled
				eGVF_NoRestart=			1024,	// do not clear when a cvar_restart is issued

			};


			

			// updates an interpreted modules' version of a cvar
			// 2007 1 7 foealg
			// currently, i think update member is not need
			void Update( float elapsedtime );
			// returns an empty string if not defined
			//void GetStringByBuffer( LPTSTR buffer, int bufsize );
			//void Reset();
			


			
			LPCTSTR GetString();

			::_FO_UTIL::Name GetName();
			::_FO_UTIL::Name GetType();

			
			
						
			static iGeneralVariableManager* i_GeneralVariableManager;
		protected:

			const ::_FO_UTIL::Name m_nameName;
			const ::_FO_UTIL::Name m_nameType;
			foString m_strValue;
			foString m_strLatchValue;

			// will create the variable with no flags if it doesn't exist
			void Set( LPCTSTR value );
			
			


			virtual void ValueUpdated()=0;


		private:

			void CheckModify();

			bool			m_bModified;			// set each time the gv is changed
			foUInt	m_uiModificationCount;	// incremented each time the gv is changed
			foUInt	m_uiFlags;



		};

		typedef GeneralVariable GV;
	}
}
#define gvRegister(gv)\
	(::_FOGGE_::_GDB_::GeneralVariable::i_GeneralVariableManager->RegisterGeneralVariable((gv)))

#define gvGet(name)\
	(::_FOGGE_::_GDB_::GeneralVariable::i_GeneralVariableManager->FindGeneralVariable((name)))
		
